local set_animation = defense_mob_api.library.set_animation
local make_sound = defense_mob_api.library.make_sound


local c_air = minetest.get_content_id("air")




local function crash_blocks(self, pos, radius)
	local p = {x=0, y=0, z=pos.z - radius}
	for z = -radius, radius
	do
		p.y = pos.y - radius
		for y = -radius, radius
		do
			p.x = pos.x - radius
			for x = -radius, radius
			do
				if x*x + y*y + z*z <= radius
				then
					
					local node = minetest.get_node_or_nil(p)
					if node
					then
						local did_something = false
						local result = erosion.get_erosion_result(node.name, 4)
						if node.name ~= result
						then
							did_something = true
							minetest.set_node(p, {name = result})
						end
						if (minetest.registered_nodes[node.name] or {groups  = {}}).groups.crumbly
						then
							did_something = true
							minetest.spawn_falling_node(p)
						end
						if did_something and math.random() < 0.1
						then
							local charge_timer = self.timers.charge_timer
							if charge_timer
							then
								charge_timer.manipulate_time(self, 1)
							end
						end
					end
				end
				p.x = p.x + 1
			end
			p.y = p.y + 1
		end
		p.z = p.z + 1
	end
end

local function crash_objects(self, pos, radius, maxweight)
	local v = self.object:getvelocity()
	for _,o in ipairs(minetest.get_objects_inside_radius(pos, radius))
	do
		if o ~= self.object
		then
			o:punch(self.object, 1.0,  {
				full_punch_interval=1.0,
				damage_groups = {fleshy=1}
				}, nil)
			if math.random() < 0.01
			then
				--stop charging prematurely
				local charge_timer = self.timers.charge_timer
				if charge_timer
				then
					charge_timer.manipulate_time(self, 1)
				end
			end
			if o:is_player()
			then
				o:add_player_velocity({x = 0, y = 1 + math.random() * vector.length(v), z = 0})
			else
				o:setvelocity({x = 0, y = 3 + math.random() * vector.length(v), z = 0})
			end
		end
	end

	return maxweight
end

local function charge(self)
	local target = self.target

	if target.ref
	then
		local pos = self.object:get_pos()
		local r = math.max(0, self.attack_range - 2)
		local dir = vector.aim(target.pos, pos)
		self.destination = vector.add(target.pos, vector.multiply(dir, target.distance * -1.3))
		self.charge_destination = self.destination
	end
end


local function set_charging_state(self, state)
	self.charging = state
	if state
	then
		self.move_speed = 9
		self.animation = self.charging_animation
		set_animation(self, "charge")
		charge(self)
		self.destination = nil
		self.charge_timer = 0
		make_sound(self, "charge", false, 2, 0.5 + (math.random() - 0.5) / 4, 32)
	else
		self.move_speed = 6
		self.animation = self.normal_animation
		set_animation(self, "attack")
		self.charge_cooldown = 100
		self.charge_destination = nil
	end
end

local function stop_charging(self)
	set_charging_state(self, false)
end

local function start_charging(self)
	defense_mob_api.library.set_up_timer(self,
		math.random(5, 10),
		stop_charging,
		"charge_timer")
	
	set_charging_state(self, true)
end





defense_mob_api.register_mob("mob_sarangay:sarangay", {
	hp_max = 120,
	collisionbox = {-0.9,-0.01,-0.9, 0.9,2.5,0.9},
	mesh = "mob_sarangay_sarangay.b3d",
	textures = {"mob_sarangay_sarangay.png"},
	makes_footstep_sound = true,
	animation = {},
	

	normal_animation = {
		idle = {a=0, b=19, rate=10},
		jump = {a=60, b=69, rate=15},
		fall = {a=70, b=89, rate=20},
		attack = {a=40, b=59, rate=15},
		move = {a=20, b=39, rate=20},
		move_attack = {a=40, b=50, rate=15},
	},

	charging_animation = {
		idle = {a=120, b=129, rate=10},
		jump = {a=90, b=109, rate=10},
		fall = {a=90, b=109, rate=10},
		attack = {a=40, b=59, rate=15},
		move = {a=90, b=109, rate=30},
		move_attack = {a=40, b=50, rate=15},
		start = {a=110, b=119, rate=15},
	},

	smart_path = true,
	mass = 12,
	move_speed = 6,
	jump_height = 1,
	armor = 0,
	attack_damage = 4,
	attack_range = 2.0,
	attack_interval = 1.0,
	step_height = 1.3,

	charging = false,
	charge_power = 0,
	charge_destination = nil,
	charge_cooldown = 0,
	on_activate = function(self, staticdata)
		set_charging_state(self, self.charging)
	end,
	
	
	on_step = function(self, dtime)
		local pos = self.object:get_pos()
		if self.charging
		then
			--TODO: replace charge timer
			
			self.destination = self.charge_destination
			
			
			local pos = self.object:get_pos()
			pos.y = pos.y + 1.5
			local dir = self.object:getvelocity()
			dir.y = 0
			dir = vector.multiply(vector.normalize(dir), 2)
			local front_pos = vector.add(pos, dir)
			
			crash_blocks(self, front_pos, 3)
			crash_objects(self, pos, 3, 10) --front
			
			
		else
			local target = self.target
			if target
			then
				if target.distance > 4 and
					self.charge_cooldown < 1 and
					math.abs(target.pos.y - pos.y) < 4 and
					math.random() < 0.1
				then
					start_charging(self)
					
				elseif target.distance < 4
				then
					self.charge_cooldown = 5
					self:hunt()
				elseif target.pos
				then
					self.charge_cooldown = self.charge_cooldown - 1
					local dir = vector.aim(target.pos, pos)
					self.destination = vector.add(target.pos, vector.multiply(dir, 12))
				end
			end
		end
	end,
})
minetest.register_alias("sarangay", "mob_sarangay:sarangay")
